package com.mylib.libcore.network.rx;


import android.content.Context;
import android.util.Log;

import com.alibaba.android.arouter.launcher.ARouter;
import com.mylib.libcore.AppContext;
import com.mylib.libcore.config.NetConfig;
import com.mylib.libcore.config.RouterConfig;
import com.mylib.libcore.network.exception.ApiException;
import com.google.gson.Gson;
import com.mylib.libcore.utils.ActivityUtil;
import com.mylib.libcore.utils.RetrofitUtil;
import com.mylib.libcore.utils.ToastUtil;
import com.mylib.libcore.utils.UIUtils;
import com.trello.rxlifecycle2.LifecycleProvider;
import com.mylib.libcore.bean.BaseBean;
import com.mylib.libcore.utils.JsonUtil;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.functions.Function;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

import static com.mylib.libcore.config.NetConfig.BASE_SUCCESS_CODE;
import static com.mylib.libcore.config.NetConfig.BASE_TOKEN_ERROR;


public class RxResultHelper {
    private static <T> ObservableTransformer<T, T> handleResult() {
        return new ObservableTransformer<T, T>() {
            @Override
            public Observable<T> apply(Observable<T> tObservable) {
                return tObservable.flatMap(new Function<T, ObservableSource<T>>() {

                    @Override
                    public ObservableSource<T> apply(T resultEntity) throws Exception {

                        BaseBean baseBean = null;
                        if (resultEntity instanceof String) {
                            Gson gson = JsonUtil.gsonBuilder.create();
                            baseBean = gson.fromJson((String) resultEntity, BaseBean.class);
                        } else if (resultEntity instanceof BaseBean) {
                            baseBean = (BaseBean) resultEntity;
                        }

                        if (baseBean != null && BASE_SUCCESS_CODE != baseBean.getCode()) {
                            Log.d("token_error","重新获取token->300->1");
                            if(baseBean.getCode()== BASE_TOKEN_ERROR){
                                ToastUtil.show("数据失效，请重新登录");
                                AppContext.getInstance().getAppPreferencesHelper().clearPreferencesHelper();
                                ActivityUtil.getInstance().clearAllActivity();
                                ARouter.getInstance().build(RouterConfig.ROUTER_ACTIVITY_LOGIN).navigation();
                            }else {
                                return Observable.error(new ApiException("网络异常", baseBean.getCode()));
                            }

                        }

                        return Observable.just(resultEntity);
                    }
                });
            }
        };
    }
    private static <T> ObservableTransformer<T, T> handleResultTouTiao() {
        return new ObservableTransformer<T, T>() {
            @Override
            public Observable<T> apply(Observable<T> tObservable) {
                return tObservable.flatMap(new Function<T, ObservableSource<T>>() {

                    @Override
                    public ObservableSource<T> apply(T resultEntity) throws Exception {
                        return Observable.just(resultEntity);
                    }
                });
            }
        };
    }


    private static <T> ObservableTransformer<T, T> handleResultTrue() {
        return new ObservableTransformer<T, T>() {
            @Override
            public Observable<T> apply(Observable<T> tObservable) {
                return tObservable.flatMap(new Function<T, ObservableSource<T>>() {

                    @Override
                    public ObservableSource<T> apply(T resultEntity) throws Exception {
                        BaseBean baseBean = null;
                        if (resultEntity instanceof String) {
                            Gson gson = JsonUtil.gsonBuilder.create();
                            baseBean = gson.fromJson((String) resultEntity, BaseBean.class);
                        } else if (resultEntity instanceof BaseBean) {
                            baseBean = (BaseBean) resultEntity;
                        }

                        return Observable.just(resultEntity);
                    }
                });
            }
        };
    }

    /**
     * @param observable
     * @param <R>    Context处理请求进行转化,返回http结果
     */
    public static <R> Observable<R> getHttpObservable(Context context, Observable<R> observable) {
        return observable
                .compose(RxUtils.<R>schedulersTransformer())
                .compose(RxUtils.<R>bindToLifecycle(context))
                .compose(RxResultHelper.<R>handleResult())
                .retryWhen(RxUtils.handleRetryWhen());//token异常去除2019/9/6
    }


    /**
     * @param observable
     * @param <R>   LifecycleProvider处理请求进行转化,返回http结果
     */
    public static <R> Observable<R> getHttpObservable(LifecycleProvider lifecycleProvider, Observable<R> observable) {
        return observable
                .compose(RxUtils.<R>schedulersTransformer())
                .compose(lifecycleProvider.bindToLifecycle())
                .compose(RxResultHelper.<R>handleResult())
                .retryWhen(RxUtils.handleRetryWhen());
    }

    /**
     * @param observable
     * @param <R>   LifecycleProvider请求不做处理,返回http结果
     */
    public static <R> Observable<R> getHttpObservableNothing(LifecycleProvider lifecycleProvider, Observable<R> observable) {
        return observable
                .compose(RxUtils.<R>schedulersTransformer())
                .compose(lifecycleProvider.bindToLifecycle())
                .compose(RxResultHelper.<R>handleResultTouTiao());

    }



    /**
     * @param observable
     * @param <R>   不拦截处理请求进行转化,返回http结果
     */
    public static <R> Observable<R> getHttpObservableNone(Context context, Observable<R> observable) {
        return observable
                .compose(RxUtils.<R>schedulersTransformer())
                .compose(RxUtils.<R>bindToLifecycle(context))
                .compose(RxResultHelper.<R>handleResultTrue());
    }
    /**
     * @param observable
     * @param <R>   不拦截处理请求进行转化,返回http结果
     */
    public static <R> Observable<R> getHttpObservableNone(LifecycleProvider lifecycleProvider, Observable<R> observable) {
        return observable
                .compose(RxUtils.<R>schedulersTransformer())
                .compose(lifecycleProvider.bindToLifecycle())
                .compose(RxResultHelper.<R>handleResultTrue());
    }

    /**
     * 获取Service
     *不拦截处理请求进行转化,返回http结果
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T create(Class<T> clazz) {
        Retrofit retrofit = new Retrofit.Builder().baseUrl(NetConfig.NET_BASE)
                .client(RetrofitUtil.getAppOkHttpClient())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build();
        return retrofit.create(clazz);
    }


}
